package com.yf1706.tools;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.fastjson.JSONArray;

@Component
public class UploadDownloadTool {
	// 文件默认路径
	public final String PATH = "D:/HRMSfiles";

	@RequestMapping("index")
	public String index() {
		return "upload";
	}

	/**
	 * 单文件上传
	 * <h1 th:inlines="text">文件上传</h1>
	 * <form action="fileUpload" method="post" enctype="multipart/form-data">
	 * <p>
	 * 选择文件: <input type="file" name="file"/>
	 * </p>
	 * <p>
	 * <input type="submit" value="提交"/>
	 * </p>
	 * </form>
	 */
	@RequestMapping("fileUpload")
	public String fileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
		System.out.println("进入fileUpload");
		// 上传文件的路径
		/*
		 * javax.servlet.ServletContext root = request.getServletContext(); String path
		 * = root.getRealPath("upload"); System.out.println(path);
		 */
		File path = new File(PATH);
		if (!path.exists()) {
			// 如果文件夹不存在， 创建文件夹
			path.mkdirs();
		}
		/* E:/JAVAEE/workspace/springbootMysql/src/main/webapp/upload */
		System.out.println(path.getAbsolutePath());
		// 文件的后缀名
		// 24f6377b02087bf40f10feb3ffd3572c10dfcf4b.jpg
		System.out.println(file.getOriginalFilename());
		String fullName = file.getOriginalFilename();
		// 获取原始文件名的最后一个.的索引
		int pos = fullName.lastIndexOf(".");
		String posName = fullName.substring(pos);
		String originalName = fullName.substring(0, pos);
		System.out.println(posName);
		// 全球唯一码
		String uuid = UUID.randomUUID().toString();
		// 生成新的文件名(原文件名+下划线+唯一码)+后缀
		String newFileName = originalName + "_" + uuid + posName;
		// 997f96b2-23e3-42ba-ac2f-d82d832ec99c.jpg
		System.out.println(newFileName);

		try {
			// 文件保存
			file.transferTo(new File(path, newFileName));
			return newFileName;
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	/**
	 * 实现多文件上传
	 * <h1 th:inlines="text">多文件上传</h1>
	 * <form action="multifileUpload" method="post" enctype="multipart/form-data" >
	 * <p>
	 * 选择文件1: <input type="file" name="file"/>
	 * </p>
	 * <p>
	 * 选择文件2: <input type="file" name="file"/>
	 * </p>
	 * <p>
	 * 选择文件3: <input type="file" name="file"/>
	 * </p>
	 * <p>
	 * <input type="submit" value="提交"/>
	 * </p>
	 * </form>
	 */
	@RequestMapping(value = "multifileUpload", method = RequestMethod.POST)
	@ResponseBody
	public List<String> multifileUpload(HttpServletRequest request) {

		List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");

		if (files.isEmpty()) {
			return null;
		}

		File path = new File(PATH);
		if (!path.exists()) {
			// 如果文件夹不存在， 创建文件夹
			path.mkdirs();
		}
		List<String> list=new ArrayList<String>();
		for (MultipartFile file : files) {

			if (file.isEmpty()) {
				continue;
			} else {
				// 文件的后缀名
				// 24f6377b02087bf40f10feb3ffd3572c10dfcf4b.jpg
				System.out.println(file.getOriginalFilename());
				String fullName = file.getOriginalFilename();
				// 获取原始文件名的最后一个.的索引
				int pos = fullName.lastIndexOf(".");
				String posName = fullName.substring(pos);
				String originalName = fullName.substring(0, pos);
				System.out.println(posName);
				// 全球唯一码
				String uuid = UUID.randomUUID().toString();
				// 生成新的文件名(原文件名+下划线+唯一码)+后缀
				String newFileName = originalName + "_" + uuid + posName;
				// 997f96b2-23e3-42ba-ac2f-d82d832ec99c.jpg
				System.out.println(newFileName);
				try {
					file.transferTo(new File(path, newFileName));
					list.add(newFileName);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return list;
	}

	// 单文件下载
	@RequestMapping("download")
	public void downLoad(HttpServletResponse response, String fileName) {
		System.out.println("进入download");
		File file = new File(PATH,fileName);
		if (file.exists()) { // 判断文件父目录是否存在
			response.setContentType("application/force-download");
			response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);

			byte[] buffer = new byte[1024];
			FileInputStream fis = null; // 文件输入流
			BufferedInputStream bis = null;

			OutputStream os = null; // 输出流
			try {
				os = response.getOutputStream();
				fis = new FileInputStream(file);
				bis = new BufferedInputStream(fis);
				int i = bis.read(buffer);
				while (i != -1) {
					os.write(buffer);
					i = bis.read(buffer);
				}

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("----------file download" + fileName);
			try {
				bis.close();
				fis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			System.out.println("文件不存在");
		}
	}

	/**
	 * 多文件下载 格式为JSON数组，每项是文件地址
	 */
	@RequestMapping("multiDownload")
	public void multiDownload(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("进入multiDownload");
		System.out.println("file_arr" + request.getParameter("file_arr"));
		JSONArray fileArr = JSONArray.parseArray(request.getParameter("file_arr"));
		Map map = new HashMap<>();
		// 设置最终输出zip文件的目录+文件名
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		String zipFileName = formatter.format(new Date()) + ".zip";
		String strZipPath = PATH + "/" + zipFileName;
		System.out.println("strZipPath:" + strZipPath);
		ZipOutputStream zipStream = null;
		FileInputStream zipSource = null;
		BufferedInputStream bufferStream = null;
		File zipFile = new File(strZipPath);

		try {
			// 构筑最终zip包的输出流
			zipStream = new ZipOutputStream(new FileOutputStream(zipFile));

			for (Object fileObej : fileArr) {
				String fileStr = (String) fileObej;
				File file = new File(PATH + "/" + fileStr);
				if (file.exists()) { // 判断文件父目录是否存在
					zipSource = new FileInputStream(file);
					/**
					 * 压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项， 称为条目，就像索引一样这里的name就是文件名, 文件名和之前的重复就会导致文件被覆盖
					 */
					ZipEntry zipEntry = new ZipEntry(fileStr);// 在压缩目录中文件的名字
					zipStream.putNextEntry(zipEntry);// 定位该压缩条目位置，开始写入文件到压缩包中
					bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
					int read = 0;
					byte[] buf = new byte[1024 * 10];
					while ((read = bufferStream.read(buf, 0, 1024 * 10)) != -1) {
						zipStream.write(buf, 0, read);
					}
				}

			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// 关闭流
			try {
				if (null != bufferStream)
					bufferStream.close();
				if (null != zipStream) {
					zipStream.flush();
					zipStream.close();
				}
				if (null != zipSource)
					zipSource.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		// 判断系统压缩文件是否存在：true-把该压缩文件通过流输出给客户端后删除该压缩文件 false-未处理
		System.out.println("a");
		if (zipFile.exists()) {
			System.out.println("b");
			this.downLoad(response, zipFileName);
			zipFile.delete();
		}

	}
}
